
#include <reg52.h>

/**
 *<@ brief region bsp config
 */

#define PINS_OF_LED_VALUE				P0		//配置数码管的J3连接的IO		//共阴极
//sbit ctrl = P1^0;					//配置啥...不记得了=.=！	应该是上一个版本里面的数码管位选		
#define PIN_OF_BEEP_J42_7				P1^1	//配置连接到蜂鸣器的管脚		//时钟主要输出IO
#define PIN_OF_J2_1							P1^2	//配置数值锁存U2的CS信号IO	//active HIGH
#define PIN_OF_J2_2							P1^3	//配置位选锁存U3的CS信号IO	//active HIGH
#define PINS_OF_BUTTON_DETECT		P2		//配置4X4矩阵J24连接的IO

sbit beep = PIN_OF_BEEP_J42_7;
sbit cs_enable_dig_select = PIN_OF_J2_1;
sbit cs_enable_dig_value = PIN_OF_J2_2;

/**
 *>
 */

//记录音调	
const unsigned char tone_tim1[]= {
	0xFC,0x0C,//0
	0xFC,0x44,//1
	0xFC,0xAC,//2
	0xFD,0x09,//3
	0xFD,0x34,//4
	0xFD,0x82,//5
	0xFD,0xC8,//6
	0xFE,0x06,//7
	0xFE,0x22,//8
	0xFE,0x56,//9
	0xFE,0x85,//10	
	0xFE,0x9A,//11
	0xFE,0xC1,//12
	0xFE,0xE4,//13
	
	0xFE,0x22,//14		//8
	0xFE,0x22,//15		//8
	};

const unsigned char music_1_table[]= {	  //音乐1 风一样的勇士 前奏
	3,6,7,8,4,6,7,8,	5,6,9,8,7,7,7,7,
	3,6,7,8,4,6,7,8,	5,6,9,8,7,7,7,7,
	};

//显示0-f对映数码管	//根据数码管 阴极、阳极切换数组选择
unsigned char code table1[]={
		0x3f,0x06,0x5b,0x4f,	0x66,0x6d,0x7d,0x07, 
		0x7f,0x6f,0x77,0x7c,	0x39,0x5e,0x79,0x71,
		0x00};	
//unsigned char code table[] = {
//		0xc0,0xf9,0xa4,0xb0, 	0x99,0x92,0x82,0xf8,
//		0x80,0x90,0x88,0x83, 	0xc6,0xa1,0x86,0x8e,
//		0xff};

//音阶
const int tone[] = {1012,956,852,759, 716,638,568,506,
					478,426,379,358, 319,284,478,478};

					
unsigned char mode_flag = 0;
	//flag 0 : 按键电子琴模式
	//flag 1 ：音乐播放模式
unsigned char tim1_th ;
unsigned char tim1_tl;
const unsigned int lengh_of_music = sizeof(music_1_table);
				
unsigned char keyscan(void);	//按键检测并返回按键值
						
unsigned char music_key(void);	//返回当前按键数值 没有消抖
void timer1_init(void);			//定时1初始化		

void main(void)
{
	int i = 0;	//控制延时时间
	int times = 0;
	unsigned char key = 0xff;	//控制按键临时变量

	//初始化定时器配置
	tim1_th =  tone_tim1[0];
	tim1_tl =  tone_tim1[1];
	
	//全局初始化、选择数码管
	//ctrl = 0;
	cs_enable_dig_select = 1;
	cs_enable_dig_value = 0;
	PINS_OF_LED_VALUE = 0x01;
	
	cs_enable_dig_select = 0;
	cs_enable_dig_value = 1;
	PINS_OF_LED_VALUE = 0x00;

	//初始化定时器寄存器
	timer1_init();

	while(1)
	{
		//扫键、得到键值、返回0xFF则没有任意按键按下
		key = music_key();	
		
		//根据按键的数值应用到数码管
		if(key == 0xff)
		{
			PINS_OF_LED_VALUE = table1[16];
		} else 
		{
			PINS_OF_LED_VALUE = table1[key];
		}
		
		
		//根据案件的数值和当前电子琴的工作状态、配置定时器相关
		if(key == 0xff)             
		{
			if(mode_flag == 0)
			{
				TR1 = 0;	//关闭电子琴
			}
			continue;	//没有按键，跳出
		} else if((key == 0x0f)&&(mode_flag == 0))	//开音乐
		{		  
			TR0 = 1;		//开启中断0	
			TR1 = 1;		//开启蜂鸣器
			mode_flag = 1;		
		} else if((key == 0x0e)&&(mode_flag == 1))	//关音乐
		{			
			TR0 = 0;
			mode_flag = 0;
		} else if (mode_flag == 0)
		{	   
			tim1_th = tone_tim1[key*2];	 
			tim1_tl = tone_tim1[key*2 + 1];
			TR1 = 1;	//开启定时器
		} else		 	//在音乐模式下按键按键 目前暂时不处理
		{
			continue;
		}
	}
}

void timer1_init(void)
{
	EA = 1;			//关中断

	TMOD = 0x11;  	//定时器工作方式1

	ET0 = 1;		//开启定时器0；	 
	TH0 = 0xD8;	 	//
	TL0 = 0xF0;		//产生0.1s的TIM0中断
//	TR0 = 1;		//用于音乐播放

	ET1 = 1;		//开启定时器1；	
	TH1 = tim1_th;	//高八位
	TL1 = tim1_tl;	//低八位		  
//	TR1 = 1;		//时能定时器1；

}

unsigned char music_key(void)	//返回当前按键数值 没有消抖
{
	unsigned char temp_key_private = 0xff;
	unsigned char temp;
	PINS_OF_BUTTON_DETECT = 0xf0;
	temp = PINS_OF_BUTTON_DETECT&0xf0;
	switch(temp)	//取出地址偏移
	{
		case 0xe0: temp_key_private = 0; break;
		case 0xd0: temp_key_private = 1; break;
		case 0xb0: temp_key_private = 2; break;
		case 0x70: temp_key_private = 3; break;
		default : return 0xff;	//没有扫描到按键
	}
	PINS_OF_BUTTON_DETECT = 0x0f;
	temp = PINS_OF_BUTTON_DETECT&0x0f;
	switch(temp)
	{
		case 0x0e: temp_key_private += 0;break;
		case 0x0d: temp_key_private += 4;break;
		case 0x0b: temp_key_private += 8;break;
		case 0x07: temp_key_private += 12;break;
		default : return 0xff;	//理论上无法达到这里
	}
	PINS_OF_BUTTON_DETECT = 0xff;
	return(temp_key_private);
}

void timer0() interrupt 1	//TIM0 定时器
{	
	static int music_private = 0;	 //用于控制音乐的播放
	static int prescale = 0;
	TH0 = 0xD8;	 	//
	TL0 = 0xF0;		//产生0.1s的TIM0中断
		 
	PINS_OF_LED_VALUE = table1[4];
	if(prescale++ ==28)
	{
		if(music_private++ == lengh_of_music)
		{
			music_private =0;
		}	
		prescale = 0;
	}
	tim1_th =  tone_tim1[2*music_1_table[music_private]]; 
	tim1_tl =  tone_tim1[2*music_1_table[music_private]+1];
	
}

void timer1() interrupt 3	//TIM1 定时器
{								   	
	TH1 = tim1_th;	//高八位
	TL1 = tim1_tl;	//低八位
	beep = ~beep;
}